package yxy.game.pm2.bean.order;

import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import org.redisson.api.RMap;

import yxy.apple.util.redisson.RedisConnection;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.db.newDao.OrderInfoDao;
import yxy.game.pm2.bean.db.po.OrderInfoPo;
import yxy.game.pm2.bean.module.BaseGameRedisLockBean;
import yxy.game.pm2.bean.module.OrderInfoModule;

/**
 * redis 订单信息  订单支付完成后创建一份到redis
 *
 * @author Dell
 */
public class OrderInfo extends BaseGameRedisLockBean {

    //bean--------------------------------------
    private String playercode;        //玩家唯一code
    private int goodsid;            //商品id
    private int serverid;            //服务器id
    private String myorderid;        //我方订单id
    private String platorderid;        //平台订单id+
    private int goodsprice;            //商品价格 分
    private int payamount;            //实际充值金额   单位分
    private int acttype;            //活动类型
    private int orderstate;            //订单状态
    private String channel;            //平台渠道
    private DateTime ordercreatetime;    //订单创建时间
    private DateTime upDateTime;        //更新时间
    private ArrayList<Currency> curs;    //奖励信息 		jsonarray[json,json]    josn:keys:rewardtype,rewardid,rewardnum
    private int addvipexp;                //奖励vip经验


    public int getGoodsid() {
        return goodsid;
    }

    public void setGoodsid(int goodsid) {
        this.goodsid = goodsid;
    }

    public String getPlayercode() {
        return playercode;
    }

    public void setPlayercode(String playercode) {
        this.playercode = playercode;
    }

    public int getServerid() {
        return serverid;
    }

    public void setServerid(int serverid) {
        this.serverid = serverid;
    }

    public String getMyorderid() {
        return myorderid;
    }

    public void setMyorderid(String myorderid) {
        this.myorderid = myorderid;
    }

    public String getPlatorderid() {
        return platorderid;
    }

    public void setPlatorderid(String platorderid) {
        this.platorderid = platorderid;
    }

    public int getGoodsprice() {
        return goodsprice;
    }

    public void setGoodsprice(int goodsprice) {
        this.goodsprice = goodsprice;
    }

    public int getPayamount() {
        return payamount;
    }

    public void setPayamount(int payamount) {
        this.payamount = payamount;
    }

    public int getActtype() {
        return acttype;
    }

    public void setActtype(int acttype) {
        this.acttype = acttype;
    }

    public int getOrderstate() {
        return orderstate;
    }

    public void setOrderstate(int orderstate) {
        this.orderstate = orderstate;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public DateTime getOrdercreatetime() {
        return ordercreatetime;
    }

    public void setOrdercreatetime(DateTime ordercreatetime) {
        this.ordercreatetime = ordercreatetime;
    }

    public DateTime getUpDateTime() {
        return upDateTime;
    }

    public void setUpDateTime(DateTime upDateTime) {
        this.upDateTime = upDateTime;
    }

    public ArrayList<Currency> getCurs() {
        return curs;
    }

    public void setCurs(ArrayList<Currency> curs) {
        this.curs = curs;
    }

    public int getAddvipexp() {
        return addvipexp;
    }

    public void setAddvipexp(int addvipexp) {
        this.addvipexp = addvipexp;
    }

    // fun --------------------------------------------------------------------------


    // redis==========================================================================

    static public String key(String playerCode) {
        return String.format("PLAYER:%s:ORDERINFO", playerCode);
    }

//	static private RedisConnection redis() {
//		return RedisManager.getInstance().getConnection(RedisType.REDIS_GAME);
//	}

    static private RMap<String, OrderInfo> touch(String playerCode) throws RedisException {
        return RedisManager.client(redis()).getMap(key(playerCode));
    }

    static public int size(String playerCode) {
        try {
            return touch(playerCode).size();
        } catch (RedisException e) {
        }
        return 0;
    }

    static public Map<String, OrderInfo> all(String playerCode) {
        try {
            Map<String, OrderInfo> ois = touch(playerCode).readAllMap();
            //缓存为空从数据库找
            if (ois == null || ois.size() <= 0) {
                List<OrderInfoPo> list = OrderInfoDao.getList(playerCode);
                if (list != null && list.size() > 0) {
                    //有数据就保存到redis
                    for (OrderInfoPo infoPo : list) {
                        OrderInfo orderInfo = toBean(infoPo);
                        touch(playerCode).put(orderInfo.getMyorderid(), orderInfo);
                    }
                }
            }
            return ois;
        } catch (RedisException e) {
            e.printStackTrace();
        }
        return new HashMap<>();
    }

    static public OrderInfo get(String playerCode, String myorderid) {
        try {
            Map<String, OrderInfo> all = all(playerCode);
            return all.get(myorderid);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    static public boolean set(String playerCode, OrderInfo oi) {
        try {
            RMap<String, OrderInfo> ois = touch(playerCode);
            ois.put(oi.getMyorderid(), oi);
            return true;
        } catch (RedisException e) {
            e.printStackTrace();
            return false;
        }
    }

    // lock==========================================================================

    static private String lockKey(String playerCode) {
        return String.format("lock:%s", key(playerCode));
    }

    static public boolean lockOrderInfo(String playerCode) throws InterruptedException {
        return tryLock(lockKey(playerCode));
    }

    static public void unlockOrderInfo(String playerCode) {
        unlock(lockKey(playerCode));
    }


    //数据归档到数据库
    public static void saveToDB(String playerCode) {
        try {
            long updateTime = System.currentTimeMillis();
            //缓存数据
            RMap<String, OrderInfo> rMap = touch(playerCode);
            //po的list
            ArrayList<OrderInfoPo> infoPoArrayList = new ArrayList<>();
            if (rMap.isExists()) {
                Map<String, OrderInfo> orderInfos = rMap.readAllMap();
                //封装到list结构进行数据库操作
                for (String key : orderInfos.keySet()) {
                    OrderInfoPo orderInfoPo = toDbBean(orderInfos.get(key), updateTime);
                    infoPoArrayList.add(orderInfoPo);
                }
                //更新数据库
                OrderInfoDao.replace(infoPoArrayList);
                //删除旧数据
                OrderInfoDao.delete(playerCode, updateTime);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //清除redis
    public static void removeAllFromRedis(String playerCode) {
        try {
            RedisManager.client(redis()).getBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    //OrderInfoPo转成OrderInfo
    public static OrderInfo toBean(OrderInfoPo orderInfoPo) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setPlayercode(orderInfoPo.getpCode());
        orderInfo.setGoodsid(orderInfoPo.getGoodsId());
        orderInfo.setServerid(orderInfoPo.getServerId());
        orderInfo.setMyorderid(orderInfoPo.getMyOrderId());
        orderInfo.setPlatorderid(orderInfoPo.getPlatOrderId());
        orderInfo.setGoodsprice(orderInfoPo.getGoodsPrice());
        orderInfo.setPayamount(orderInfoPo.getPayaMount());
        orderInfo.setActtype(orderInfoPo.getActType());
        orderInfo.setOrderstate(orderInfoPo.getOrderState());
        orderInfo.setChannel(orderInfoPo.getChannel());
        orderInfo.setOrdercreatetime(new DateTime(orderInfoPo.getOrderCreateTime()));
        orderInfo.setUpDateTime(new DateTime(orderInfoPo.getUpDateTime()));
        JSONArray jsonArray = JSONArray.parseArray(orderInfoPo.getCurs());
        ArrayList<Currency> list = new ArrayList<>();
        //判空处理
        if (jsonArray !=null && jsonArray.size()>0){
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject currencyJson = jsonArray.getJSONObject(i);
                Currency currency = new Currency();
                currency.setType(CurrencyType.valueOf(currencyJson.getString("type")));
                currency.setDataId(currencyJson.getInteger("dataId"));
                currency.setNumber(currencyJson.getInteger("number"));
                list.add(currency);
            }
        }
        orderInfo.setCurs(list);
        orderInfo.setAddvipexp(orderInfoPo.getAddVipExp());
        return orderInfo;
    }

    //OrderInfo转成OrderInfoPo
    public static OrderInfoPo toDbBean(OrderInfo orderInfo, long updateTime) {
        OrderInfoPo po = new OrderInfoPo();
        po.setpCode(orderInfo.getPlayercode());
        po.setGoodsId(orderInfo.getGoodsid());
        po.setServerId(orderInfo.getServerid());
        po.setMyOrderId(orderInfo.getMyorderid());
        po.setPlatOrderId(orderInfo.getPlatorderid());
        po.setGoodsPrice(orderInfo.getGoodsprice());
        po.setPayaMount(orderInfo.getPayamount());
        po.setActType(orderInfo.getActtype());
        po.setOrderState(orderInfo.getOrderstate());
        po.setChannel(orderInfo.getChannel());
        po.setOrderCreateTime(orderInfo.getOrdercreatetime().toDate());
        po.setUpDateTime(orderInfo.getUpDateTime().toDate());
        ArrayList<Currency> curs = orderInfo.getCurs();
        //集合转成jsonarray保存
        JSONArray jsonArray = new JSONArray();
        if (curs != null) {
            for (Currency cur : curs) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", cur.getType());
                jsonObject.put("dataId", cur.getDataId());
                jsonObject.put("number", cur.getNumber());
                jsonArray.add(jsonObject);
            }
        }
        po.setCurs(jsonArray.toString());
        po.setAddVipExp(orderInfo.getAddvipexp());
        po.setSaveToDbTime(updateTime);
        return po;
    }


    @Override
    public String toString() {
        return "OrderInfo{" +
                "playercode='" + playercode + '\'' +
                ", goodsid=" + goodsid +
                ", serverid=" + serverid +
                ", myorderid='" + myorderid + '\'' +
                ", platorderid='" + platorderid + '\'' +
                ", goodsprice=" + goodsprice +
                ", payamount=" + payamount +
                ", acttype=" + acttype +
                ", orderstate=" + orderstate +
                ", channel='" + channel + '\'' +
                ", ordercreatetime=" + ordercreatetime +
                ", upDateTime=" + upDateTime +
                ", curs=" + curs +
                ", addvipexp=" + addvipexp +
                '}';
    }
}
